<?php

namespace App\Http\Controllers\Car;

use App\Helpers\ResponseData;
use App\Http\Controllers\Api\Wxpaybatches;
use App\Http\Controllers\Controller;
use App\Models\Car\Reimburse;
use App\Models\Car\ReimburseDetail;
use Illuminate\Http\Request;
use Modules\Manager\Entities\Manager;
use Illuminate\Support\Facades\DB;
use App\Models\ConfigTable;
use Modules\Manager\Entities\ModelHasPermission;
use App\Http\Controllers\Wx\SendTemplateController;

class ReimburseController extends Controller
{
    use ResponseData;
    public function index(Reimburse $model,Request $request) {
        $size = $request->input('size',10);
        if($request->filled('start')&&$request->filled('end')){
            $model = $model->whereBetween('created_at',[$request->start,$request->end]);
        }
        if($request->filled('status')){
            $model = $model->where('status',$request->status);
        }
        if($request->filled('type')){
            $model = $model->where('type',$request->type);
        }
        if($request->filled('is_month')){
            $model = $model->where('is_month',$request->is_month);
        }
        if($request->filled('department')){
            $model = $model->where(function($query)use($request){
                $user = $request->user();
                return $query->where('department',$request->department)->orWhere('copy_id',$user->id);
            });
        }
        if($request->filled('user_id')){
            $model = $model->where('user_id',$request->user_id);
        }
        $model = $model->whereNull('deleted_at')->with('list');
        if($request->filled('search')){
            $search = $request->search;
            $model = $model->where('operator','like','%'.$search.'%')->orWhere('pro','like','%'.$search.'%')->orWhere('remark','like','%'.$search.'%')->orWhereHas('list', function($query)use($search) {
                $query->where('project', 'like', '%'.$search.'%')->orWhere('remark', 'like', '%'.$search.'%');
            });
        }
        $data = $model->orderBy('id','desc')->paginate($size);
        return $this->success($data);
    }
    // 报销汇总
    public function totals(Reimburse $model,Request $request) {
        $model = $model->query()->selectRaw("SUM(total_money) as total_money_count");
        // $size = $request->input('size',10);
        if($request->filled('start')&&$request->filled('end')){
            $model = $model->whereBetween('created_at',[$request->start,$request->end]);
        }
        if($request->filled('status')){
            $model = $model->where('status',$request->status);
        }
        if($request->filled('type')){
            $model = $model->where('type',$request->type);
        }
        if($request->filled('is_month')){
            $model = $model->where('is_month',$request->is_month);
        }
        if($request->filled('department')){
            $model = $model->where(function($query)use($request){
                $user = $request->user();
                return $query->where('department',$request->department)->orWhere('copy_id',$user->id);
            });
        }
        $model = $model->whereNull('deleted_at');
        if($request->filled('search')){
            $search = $request->search;
            $model = $model->where('operator','like','%'.$search.'%')->orWhere('pro','like','%'.$search.'%')->orWhere('remark','like','%'.$search.'%')->orWhereHas('list', function($query)use($search) {
                $query->where('project', 'like', '%'.$search.'%')->orWhere('remark', 'like', '%'.$search.'%');
            });
        }
        $data = $model->first();
        return $this->success($data);
    }
    // 新增报销
    public function store(Reimburse $model,Request $request){
        $data = $request->all();
        $data['out_batch_no'] = date('YmdHis').rand(0,9999).time();
        $data['order_sn'] = $this->getSn($request->type);
        $this->buildDetail($request,$data['order_sn'],$data['out_batch_no'],$data['type']);
        unset($data['contents']);
        $model->fill($data);
        $model->save();
        // 这里需要通知审核人，有待审核报销-公众号消息推送-审核人是managers员工有权限ID是202的所有人（会有多个审核人，有wechat_openid的每个都要发推送消息）
        $msg = [
            'order_sn'=>$data['order_sn'],
            'status'=>1,
            'type'=>$data['type'],
            'money'=>$data['total_money'],
            'page'=>'pages/admin/reimburse/reimburse?status=1',
        ];
        $this->sendMsgByAdminUser($msg);
        // 如果有抄送人，需要发送消息给抄送人
        if($request->filled('copy_id')){
            $this->sendMsgByCopyUser($msg, $request->copy_id);
        }
        return $this->success('保存成功');
    }
    // 新增月结报销
    public function storeMonth(Reimburse $model,Request $request){
        $data = $request->all();
        $model->fill($data);
        $model->save();
        return $this->success('保存成功');
    }
    protected function buildDetail($request,$order_sn,$out_batch_no,$type){
        // 按数据生成报销项
        $contents = $request->contents;
        $data = [];
        for ($i=0;$i<count($contents);$i++){
            $data[$i]= [
                'order_sn'=> $order_sn,
                'out_batch_no'=> $out_batch_no,
                'type'=> $type,
                'created_at'=>now(),
                'money'=>$contents[$i]['money'],
                'user_id'=>$contents[$i]['user_id'],
                'user_type'=>$contents[$i]['user_type'],
                'project'=>$contents[$i]['project'],
                'images'=>$contents[$i]['images'],
                'remark'=>$contents[$i]['remark'],
            ];
        }

        if(count($data)>0){
            DB::table('reimburse_details')->insert($data);
        }
    }
    // 给审核人发送模板消息
    private function sendMsgByAdminUser($msgs){
        $userarr = ModelHasPermission::query()
            ->where('permission_id','202')
            ->pluck('model_id');
        $wechat_openidarr = Manager::query()->whereIn('id',$userarr)->pluck('wechat_openid');
        foreach($wechat_openidarr as $openid){
            if (!empty($openid)) {
                $msg = [
                    'openid'=>$openid,
                    'order_sn'=>$msgs['order_sn'],
                    'status'=>$msgs['status'],
                    'type'=>$msgs['type'],
                    'money'=>$msgs['money'],
                    'page'=>$msgs['page'],
                ];
                (new SendTemplateController())->sendTemplateBx($msg);
                info(json_encode($msg));
            }
        }
    }
    // 给打款人发送模板消息-吴英明
    private function sendMsgByPayUser($msgs){
        $msg = [
            // 'openid'=>'oZhJ0w7OYJcSSDKZqAG05DG9M_mk', // 个人测试
            'openid'=>'oZhJ0w51v4F7BUUpeQNSyRkAhdRE', // 吴英明
            'order_sn'=>$msgs['order_sn'],
            'status'=>$msgs['status'],
            'type'=>$msgs['type'],
            'money'=>$msgs['money'],
            'page'=>$msgs['page'],
        ];
        (new SendTemplateController())->sendTemplateBx($msg);
        info(json_encode($msg));
    }
    // 给抄送人发送模板消息
    private function sendMsgByCopyUser($msgs, $copy_id){
        $copy_user = Manager::query()->where('id',$copy_id)->first();
        if ($copy_user&&$copy_user->wechat_openid) {
            $msg = [
                'openid'=>$copy_user->wechat_openid,
                'order_sn'=>$msgs['order_sn'],
                'status'=>$msgs['status'],
                'type'=>$msgs['type'],
                'money'=>$msgs['money'],
                'page'=>$msgs['page'],
            ];
            (new SendTemplateController())->sendTemplateBx($msg);
            info(json_encode($msg));
        }
    }
    //设置订单号
    private function getSn($type){
        $car = Reimburse::query()
            ->select('id')
            ->where('id','>',0)
            ->orderByDesc('id')
            ->first();
        if($car){
            $num = $car->id+1;
        }else{
            $num = 1;
        }
        if ($num<10) {
            $num = '000'.$num;
        } elseif ($num<100) {
            $num = '00'.$num;
        } elseif ($num<1000) {
            $num = '0'.$num;
        }
        if ($type==1) {
            return 'shbx'.date('Ymd',time()).$num;
        } elseif ($type==2) {
            return 'zcbx'.date('Ymd',time()).$num;
        } elseif ($type==3) {
            return 'gzbx'.date('Ymd',time()).$num;
        } elseif ($type==4) {
            return 'bybx'.date('Ymd',time()).$num;
        }
    }
    // 获取报销详情
    public function edit(Reimburse $model,Request $request){
        $data = $model->find($request->id);
        $data->contents = ReimburseDetail::query()->where('order_sn',$data->order_sn)->get();
        return $this->success($data);
    }
    // 更新报销数据
    public function update(Reimburse $model,Request $request){
        $data = $model->find($request->id);
        if ($request->filled('contents')) {
            // 如果有提交项目详情，先删后增
            ReimburseDetail::query()->where('order_sn',$data->order_sn)->delete();
            $this->buildDetail($request,$data->order_sn,$data->out_batch_no,$data->type);
        }
        if ($request->status==2) {
            // 如果更新为已拒绝:status==2。需要给发起人发送公众号消息
            $user = Manager::query()->where('id',$data->user_id)->first();
            if ($user&&$user->wechat_openid) {
                // 消息发送openid：$user->wechat_openid
                $msg = [
                    'openid'=>$user['wechat_openid'],
                    'order_sn'=>$data['order_sn'],
                    'status'=>2,
                    'type'=>$data['type'],
                    'money'=>$data['total_money'],
                    'page'=>'pages/admin/reimburse/reimburse?status=2',
                ];
                (new SendTemplateController())->sendTemplateBx($msg);
                info(json_encode($msg));
            }
        }
        $savedata = $request->all();
        unset($savedata['contents']);
        $data->update($savedata);
        return $this->success('修改成功');
    }
    // 更新月结报销数据
    public function updateMonth(Reimburse $model,Request $request){
        $data = $model->find($request->id);
        $savedata = $request->all();
        $data->update($savedata);
        return $this->success('修改成功');
    }
    // 删除报销数据
    public function destory(Reimburse $model,Request $request){
        $data = $model->find($request->id);
        $data->deleted_at = now();
        $data->save();
        return $this->success('删除成功');
    }
    // 报销审核：报销状态status：1待审核，2已拒绝，3报销失败，4报销成功
    public function examine(Reimburse $model,Request $request){
        // 找到当前报销记录
        $data = $model->find($request->id);
        if(!$data){
            return $this->failed('报销记录不存在!',201);
        }
        // 找到当前报销记录关联的报销项目-按项目内容进行报销
        $contents = ReimburseDetail::query()->where('order_sn',$data->order_sn)->get();
        foreach ($contents as $v){
            // 找到单个项目记录
            $item = ReimburseDetail::query()->where('id',$v->id)->first();
            // 记录里有payment_at商户号打款成功时间的，过滤掉，只处理打款失败和未打款的
            if (!$item->payment_at) {
                if ($v->user_type==1) {
                    // 员工报销
                    $user = Manager::query()->where('id',$v->user_id)->first();
                }
                if ($v->user_type==2) {
                    // 出勤人员报销-这里是存在配置里的，通过id查找
                    $cqry = ConfigTable::query()->where('key','cqrykey')->value('value');
                    if($cqry){
                        $arr = json_decode($cqry,true);
                        $user_id = $v->user_id;
                        $foundObjects = array_filter($arr, function ($object) use ($user_id) {
                            return $object['id'] === $user_id;
                        });
                        $user = array_shift($foundObjects);
                    }
                }
                if ($user&&$user['wechat_openid']) {
                    // 这里操作微信商户号打款----打款金额字段$item->money，打款openid：$user['wechat_openid']
                    // 金额小于0.1，无法打款
                    if ($item->money>=0.1) {
                        $arr = (new Wxpaybatches())->wxBatches($user['wechat_openid'],$item->money,$item->out_batch_no);
                        info('获取打款结果'.json_encode($arr));
                        if ($arr&&isset($arr['batch_id'])) {
                            // 需要发送公众号消息推送：报销成功-发送给报销对象
                            // $msg = [
                            //     'openid'=>$user['wechat_openid'],
                            //     'order_sn'=>$data['order_sn'],
                            //     'status'=>4,
                            //     'type'=>$data['type'],
                            //     'money'=>$item->money,
                            //     'page'=>'pages/admin/reimburse/reimburse?status=4',
                            // ];
                            // (new SendTemplateController())->sendTemplateBx($msg);
                            // info(json_encode($msg));
                            // 打款成功后-更新为报销成功
                            // $item->payment_at = now(); // 商户号打款成功时间
                            // $item->save();
                            // 需要发送公众号消息推送：待支付大于1000元的-发送给管理员-吴英明
                            if($item->money>0.1){
                                $msg = [
                                    'order_sn'=>$data['order_sn'],
                                    'status'=>5,
                                    'type'=>$data['type'],
                                    'money'=>$item->money,
                                    'page'=>'pages/admin/reimburse/reimburse?status=4',
                                ];
                                $this->sendMsgByPayUser($msg);
                            }
                        } else {
                            // 这里需要通知审核人，有报销失败-公众号消息推送-审核人是managers员工有权限ID是202的所有人（会有多个审核人，有wechat_openid的每个都要发推送消息）
                            $msg = [
                                'order_sn'=>$data['order_sn'],
                                'status'=>3,
                                'type'=>$data['type'],
                                'money'=>$item->money,
                                'page'=>'pages/admin/reimburse/reimburse?status=3',
                            ];
                            $this->sendMsgByAdminUser($msg);
                            // 打款失败就-更新为报销失败，并记录失败原因
                            $item->fail_reason = $arr['message']; // 报销失败原因-一般是微信返回来的，比如账户余额不足之类的
                            $item->save();
                            $data->status = 3; // 3报销失败
                            $data->examine_at = now(); // 审核时间
                            $data->fail_reason = $arr['message']; // 报销失败原因-一般是微信返回来的，比如账户余额不足之类的，如果是因为openid不存在的，就提示未绑定公众号openid，请联系管理员处理
                            $data->save();
                            return $this->success($arr['message']);
                        }
                    } else {
                        // 这里需要通知审核人，有报销失败-公众号消息推送-审核人是managers员工有权限ID是202的所有人（会有多个审核人，有wechat_openid的每个都要发推送消息）
                        $msg = [
                            'order_sn'=>$data['order_sn'],
                            'status'=>3,
                            'type'=>$data['type'],
                            'money'=>$item->money,
                            'page'=>'pages/admin/reimburse/reimburse?status=3',
                        ];
                        $this->sendMsgByAdminUser($msg);
                        // 打款失败就-更新为报销失败，并记录失败原因
                        $item->fail_reason = "报销金额不足0.1，打款失败"; // 报销失败原因-一般是微信返回来的，比如账户余额不足之类的
                        $item->save();
                        $data->status = 3; // 3报销失败
                        $data->examine_at = now(); // 审核时间
                        $data->fail_reason = "报销金额不足0.1，打款失败"; // 报销失败原因-一般是微信返回来的，比如账户余额不足之类的，如果是因为openid不存在的，就提示未绑定公众号openid，请联系管理员处理
                        $data->save();
                        return $this->success("报销金额不足0.1，打款失败");
                    }

                } else {
                    // 这里需要通知审核人，有报销失败-公众号消息推送-审核人是managers员工有权限ID是202的所有人（会有多个审核人，有wechat_openid的每个都要发推送消息）
                    $msg = [
                        'order_sn'=>$data['order_sn'],
                        'status'=>3,
                        'type'=>$data['type'],
                        'money'=>$item->money,
                        'page'=>'pages/admin/reimburse/reimburse?status=3',
                    ];
                    $this->sendMsgByAdminUser($msg);
                    // 没有openid的直接失败
                    $item->fail_reason = '未绑定公众号openid，请联系管理员处理'; // 报销失败原因
                    $item->save();
                    $data->status = 3; // 3报销失败
                    $data->examine_at = now(); // 审核时间
                    $data->fail_reason = '未绑定公众号openid，请联系管理员处理'; // 报销失败原因-一般是微信返回来的，比如账户余额不足之类的，如果是因为openid不存在的，就提示未绑定公众号openid，请联系管理员处理
                    $data->save();
                    return $this->success('未绑定公众号openid，请联系管理员处理');
                }
            }
        }
        // 如果全部打款成功-更新当前报销记录为成功
        $data->status = 4; // 4报销成功
        $data->payment_at = now(); // 商户号打款成功时间
        $data->examine_at = now(); // 审核时间
        $data->save();
        return $this->success('打款成功');
    }
}
